package cl.foursoft.eee.util.CalculosMatematicos;

import java.util.ArrayList;
import java.util.List;

import cl.foursoft.eee.dao.transferObject.AlternativaDeInversionTO;
import cl.foursoft.eee.dao.transferObject.EvaluacionEconomicaTO;
import cl.foursoft.eee.dao.transferObject.FlujosEvaluacionTO;
import cl.foursoft.eee.dao.transferObject.ParametrosEvaluacionTO;
import cl.foursoft.eee.dao.transferObject.RequerimientoEnergeticoTO;

public class EvaluacionEconomicaUtil {

	VANUtil van;// = new VANUtil(7);
	
	public EvaluacionEconomicaUtil(){
		//
	}
	
	 
	public EvaluacionEconomicaTO obtenerEvaluacion(RequerimientoEnergeticoTO req, AlternativaDeInversionTO alternativa, ParametrosEvaluacionTO parametro){
		
		EvaluacionEconomicaTO evaluacionActual = new EvaluacionEconomicaTO();
		
		double valorPresenteAnterior = 0;
		double valorPresente = 0;
		double requerimientoEdificio = req.getRequerimientoEnergeticoTotal();
		double requerimientoAlternativa = alternativa.getRequerimientoEnergeticoTotal();
		double costoEdificio= 0;  
		double costoAlternativa = 0; 
		int	 payBack = 1;
		double flujo = 0f;
		double flujoAcumulado = 0;
	 
		/*PROCESO
		 * 1. Calcuar el valor presente del combustible (vp)
		 * 2. Calcular los costos (req ed x vp && req alt x vp)
		 * 3. Calcular diferencia de costos -> ahorro
		 * 4. Calcular Flujo 0   = inversion - ahorro0 
		 * 5. Calcular Flujos >0 = ahorro(n) 
		 * 6. Con ese flujo se calcular VAN, con los flujos de VAN se calcula TIR
		 * 
		 * */		
		evaluacionActual.setIdAlternativa(alternativa.getIdAlternativa());
		evaluacionActual.setIdParametro(parametro.getIdEvaluacion());
		evaluacionActual.setDescripcionAlternativa(alternativa.getDescripcionAlternativa()); 
		
		double flujosNetos[];
		double flujosNetosAcumulados[];
		double valores[];
		
		flujosNetos = new double[parametro.getHorizonteEvaluacion()];
		flujosNetosAcumulados = new double[parametro.getHorizonteEvaluacion()+1];
		valores = new double[parametro.getHorizonteEvaluacion()+1];
		
		//Inversion
		valorPresenteAnterior = parametro.getTarifaFinal();
		costoEdificio = requerimientoEdificio  * valorPresenteAnterior;//req*valor
		costoAlternativa = requerimientoAlternativa * valorPresenteAnterior;
		flujo = +costoEdificio - costoAlternativa;
		flujoAcumulado = -(alternativa.getInversionAlternativa()) + flujo;
		
		flujosNetosAcumulados[0] = flujoAcumulado;
		valores[0] = valorPresenteAnterior;
		
		
		//armar el array con los Flujos
		for (int i = 0 ; i<parametro.getHorizonteEvaluacion() ; i++){

				valorPresente = valorPresenteAnterior * (1 + (parametro.getVariacionPrecio()/100)); // ValorPresenteCombustible
				valorPresenteAnterior = valorPresente;
				valores[i+1] = valorPresente;
				
				costoEdificio = requerimientoEdificio  * valorPresenteAnterior;//req*valor
				costoAlternativa = requerimientoAlternativa * valorPresenteAnterior;
				flujo = +costoEdificio - costoAlternativa;
				
				flujosNetos[i] = flujo;
				
				if(flujoAcumulado<0){
					payBack++;
				}
				
				flujoAcumulado +=flujo;
				flujosNetosAcumulados[i+1] = flujoAcumulado;
		}
		
		evaluacionActual.setFlujos(flujosNetos);
		evaluacionActual.setFlujosAcumulados(flujosNetosAcumulados);
		evaluacionActual.setValores(valores);
		
		//CALCULO DE VAN Y SETEAR
		VANUtil van = new VANUtil(parametro.getHorizonteEvaluacion());
		van.setInversion(alternativa.getInversionAlternativa());
		van.setFlujos(flujosNetos);
		
		evaluacionActual.setValorVan( van.getVan(parametro.getTasaDescuento()/100) );
		
		//CALCULO DE TIR y SETEAR
		TIRUtil tir = new TIRUtil(van);
		evaluacionActual.setValorTir(tir.getTIR());
		
		//SETEAR PAYBACK
		evaluacionActual.setValorPayBack(payBack);
		
		//Guardar en la base de datos (EvaluacionEconomicaTO)
		
		return evaluacionActual;

	}
	public List<FlujosEvaluacionTO> obtenerFlujos(AlternativaDeInversionTO alternativa, ParametrosEvaluacionTO parametro , RequerimientoEnergeticoTO req ){
		List<FlujosEvaluacionTO> resp = new ArrayList<FlujosEvaluacionTO>();
		
		FlujosEvaluacionTO f = new FlujosEvaluacionTO();
	 
		
		//--
		double valorPresenteAnterior = 0;
		double valorPresente = 0;
		double requerimientoEdificio = req.getRequerimientoEnergeticoTotal();
		double requerimientoAlternativa = alternativa.getRequerimientoEnergeticoTotal();
		double costoEdificio= 0;  
		double costoAlternativa = 0; 
		int	 payBack = 1;
		double flujo = 0f;
		double flujoAcumulado = 0;
	 
		/*PROCESO
		 * 1. Calcuar el valor presente del combustible (vp)
		 * 2. Calcular los costos (req ed x vp && req alt x vp)
		 * 3. Calcular diferencia de costos -> ahorro
		 * 4. Calcular Flujo 0   = inversion - ahorro0 
		 * 5. Calcular Flujos >0 = ahorro(n) 
		 * 6. Con ese flujo se calcular VAN, con los flujos de VAN se calcula TIR
		 * 
		 * */		
		
		double flujosNetos[];
		double flujosNetosAcumulados[];
		double valores[];
		
		flujosNetos = new double[parametro.getHorizonteEvaluacion()];
		flujosNetosAcumulados = new double[parametro.getHorizonteEvaluacion()+1];
		valores = new double[parametro.getHorizonteEvaluacion()+1];
		
		//Inversion
		valorPresenteAnterior = parametro.getTarifaFinal();
		costoEdificio = requerimientoEdificio  * valorPresenteAnterior;//req*valor
		costoAlternativa = requerimientoAlternativa * valorPresenteAnterior;
		flujo = +costoEdificio - costoAlternativa;
		flujoAcumulado = -(alternativa.getInversionAlternativa()) + flujo;
		
		flujosNetosAcumulados[0] = flujoAcumulado;
		valores[0] = valorPresenteAnterior;

		f.setAnio(0);
		f.setFlujosNeto(flujo);
		f.setFlujosAcumulado(flujoAcumulado);
		f.setVariacionPrecio(valorPresenteAnterior);

		resp.add(f);
		
		//armar el array con los Flujos
		for (int i = 0 ; i<parametro.getHorizonteEvaluacion() ; i++){
			   f = new FlujosEvaluacionTO();
				valorPresente = valorPresenteAnterior * (1 + (parametro.getVariacionPrecio()/100)); // ValorPresenteCombustible
				valorPresenteAnterior = valorPresente;
	 
				
				costoEdificio = requerimientoEdificio  * valorPresenteAnterior;//req*valor
				costoAlternativa = requerimientoAlternativa * valorPresenteAnterior;
				flujo = +costoEdificio - costoAlternativa;
				
	  
				if(flujoAcumulado<0){
					payBack++;
				}
				
				flujoAcumulado +=flujo;
				
				f.setAnio(i+1);
				f.setFlujosNeto(flujo);
				f.setFlujosAcumulado(flujoAcumulado);
				f.setVariacionPrecio(valorPresenteAnterior);

				resp.add(f);
		}
 
		//--
		return resp;
	}
	public void calcularAhorro(){
		
	}
	public void calcularFlujoNetoPerCero(){
		
	}
	public void calcularFlujoNetoPerN(){
		
	}
	public void calcularFllujoAcumuladoSimple(){
		
	}
}
